package com.sc.nft.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.DepartmentWalletDao;
import com.sc.nft.dao.DepartmentWalletDetailDao;
import com.sc.nft.dao.UserInfoDao;
import com.sc.nft.entity.*;
import com.sc.nft.enums.ApprovalStatusEnum;
import com.sc.nft.enums.ExpenditureRecordTypeEnum;
import com.sc.nft.enums.MarketLevelEnum;
import com.sc.nft.enums.WalletDetailTypeEnum;
import com.sc.nft.enums.wallet.DepartmentDetailTypeEnum;
import com.sc.nft.enums.wallet.DepartmentTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.UserWalletService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.sc.nft.service.DepartmentWalletService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 部门钱包表服务接口实现
 *
 * @author zxy
 * @since 2023-12-18 18:02:52
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DepartmentWalletServiceImpl implements DepartmentWalletService {
    private final DepartmentWalletDao departmentWalletDao;
    private final DepartmentWalletDetailDao departmentWalletDetailDao;
    private final UserInfoDao userInfoDao;
    private final UserWalletService userWalletService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBalance(DepartmentTypeEnum type, MarketLevelEnum marketLevel, String orderNo,  BigDecimal amount) {
        departmentWalletDao.addBalance(type,amount);
        DepartmentWalletDetail detail = new DepartmentWalletDetail();
        detail.setDepartmentType(type);
        detail.setMarketLevel(marketLevel);
        detail.setOrderNo(orderNo);
        detail.setType(DepartmentDetailTypeEnum.ADD);
        detail.setAmount(amount);
        detail.setStatus(ApprovalStatusEnum.PASS);
        detail.insert();
    }

    @Override
    public Page<DepartmentWallet> page(Page page) {
        return departmentWalletDao.page(page);
    }



    @Override
    public Page<DepartmentWalletDetail> record(DepartmentTypeEnum departmentType, Long userId,DepartmentDetailTypeEnum type,MarketLevelEnum marketLevel,ApprovalStatusEnum status, String orderNo, Date startTime, Date endTime, Page page) {
        return departmentWalletDetailDao.record(departmentType, userId,type,marketLevel,status, orderNo, startTime, endTime, page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transfer(DepartmentTypeEnum departmentType, SysMember sysMember, String userTel, BigDecimal amount, String applyRemark) {
        DepartmentWallet departmentWallet = departmentWalletDao.getByType(departmentType);
        Assert.isTrue(NumberUtil.isGreaterOrEqual(departmentWallet.getBalance(),amount),()-> new GlobalRunTimeException("账户余额不足"));
        UserInfo userInfo = userInfoDao.getOneByUserTel(userTel);
        Assert.notNull(userInfo,()-> new GlobalRunTimeException("手机号不存在"));
        departmentWalletDao.freeze(departmentType,amount);
        DepartmentWalletDetail detail = new DepartmentWalletDetail();
        detail.setDepartmentType(departmentType);
        detail.setType(DepartmentDetailTypeEnum.TRANSFER);
        detail.setAmount(amount);
        detail.setUserId(userInfo.getId());
        detail.setApplyRemark(applyRemark);
        detail.setStatus(ApprovalStatusEnum.APPROVAL);
        detail.setApplyId(sysMember.getId());
        detail.insert();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revoke(Long id, SysMember sysMember) {
        DepartmentWalletDetail detail = departmentWalletDetailDao.getById(id);
        Assert.isTrue(ObjectUtil.isNotNull(detail)&&detail.getType()==DepartmentDetailTypeEnum.TRANSFER,()->new GlobalRunTimeException("未找到记录"));
        Assert.isTrue(detail.getStatus()==ApprovalStatusEnum.APPROVAL,()->new GlobalRunTimeException("审批状态已改变，不允许撤销操作"));
        Assert.isTrue(detail.getApplyId().longValue()==sysMember.getId().longValue(),()->new GlobalRunTimeException("权限不足，需由申请人撤销"));
        departmentWalletDao.revoke(detail.getDepartmentType(),detail.getAmount());
        departmentWalletDetailDao.updateApprovalStatus(id,ApprovalStatusEnum.REVOKE);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approval(Long id, Boolean status, String approvalRemark, SysMember sysMember) {
        DepartmentWalletDetail detail = departmentWalletDetailDao.getById(id);
        Assert.isTrue(ObjectUtil.isNotNull(detail)&&detail.getType()==DepartmentDetailTypeEnum.TRANSFER,()->new GlobalRunTimeException("未找到记录"));
        Assert.isTrue(detail.getStatus()==ApprovalStatusEnum.APPROVAL,()->new GlobalRunTimeException("该数据当前状态不是审批中，请刷新后再试"));
        detail.setApprovalId(sysMember.getId());
        detail.setApprovalRemark(approvalRemark);
        if(status){
            departmentWalletDao.subFreeze(detail.getDepartmentType(),detail.getAmount());
            detail.setStatus(ApprovalStatusEnum.PASS);
            userWalletService.addIncome(detail.getUserId(),null,detail.getAmount(),BigDecimal.ZERO, WalletDetailTypeEnum.BACKSTAGE_ADD, ExpenditureRecordTypeEnum.BACKSTAGE_ADD,"部门奖励");
        }else{
            Assert.notBlank(approvalRemark,()->new GlobalRunTimeException("请填写拒绝原因"));
            departmentWalletDao.revoke(detail.getDepartmentType(),detail.getAmount());
            detail.setStatus(ApprovalStatusEnum.REFUSE);
        }
        detail.updateById();
    }
}